/*
    定义B+数相关数据结构和函数
    （1）NewBPTreeNode：用于创建一个全新的B+树节点。
    （2）CreateBPTree：创建一个空白的B+树。
    （3）NewIndexNode：根据一个Record存储的数据创建一个索引节点。
    （4）Insert2NotFull：向非空节点插入索引节点。
    （5）NodeSplit：实现B+树的节点分裂操作。
    （6）InsertNode：将一条记录Record的第col列的数据以IndexNode的形式存储到B+树中作为索引。
    （7）Search4EqualInterval：B+树上的精确查询函数。
    （8）Search4Interval：B+树上的范围查询函数。
    （9）SaveBPTree：通过调用SaveNode2File将BPTree存储为一个索引文件。
    （10）SaveNode2File：通过递归地遍历B+树将所有节点依次写入文件中。
    （11）LoadBPTree：通过调用LoadNode将索引文件读取到内存中的BPTree类中，以便查询。
    （12）LoadNode：通过递归地遍历B+树将所有节点依次读入内存中。

*/
#ifndef BPTREE_HEAD_DEFINE
#define BPTREE_HEAD_DEFINE

#include "struct.h"
#include<unistd.h>
#include<stdlib.h>
#include<string>
#include<fcntl.h>
#include<iostream>

#define INDEX_PREFIX "index_col_" // 索引文件名前缀


class BPTree {
public:
    // 创建一个节点对象
    BPTreeNode* NewBPTreeNode();

    // 创建B+树
    BPTreeNode* CreateBPTree();

    // 创建一个索引节点
    IndexNode NewIndexNode(const Record& record, int col);

    // 插入未满的节点中
    void Insert2NotFull(BPTreeNode* node, const IndexNode& indexNode);

    // 节点分裂
    int NodeSplit(BPTreeNode* parent, int pos, BPTreeNode* child);

    // 插入节点
    BPTreeNode* InsertNode(BPTreeNode* root, const Record& record, int col);

    // 搜索特定属性值
    // result:结果数组 num:最大结果数，被MAX_RESULT_NUM限制
    void Search4EqualInterval(BPTreeNode* root, int value, int64_t *result, int &num);

    // 搜索属性值在[lowerBound,upperBound]范围内的记录
    void Search4Interval(BPTreeNode* root, int lowerBound, int upperBound, int64_t *result, int &num);

    // 保存B+树
    void SaveBPTree(BPTreeNode* root, int col);

    // 将B+树节点写入文件
    void SaveNode2File(int &fd, BPTreeNode *node);

    // 读取B+树
    BPTreeNode *LoadBPTree(int col);

    // 读取B+树节点
    // preLeafNode:前一个叶子节点
    BPTreeNode *LoadNode(int &fd, BPTreeNode* &preLeafNode);
};

#endif // BPTREE_HEAD_DEFINE
